/**
 * Spring Security配置
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.config;


import com.sxf.crm.security.JwtRequestFilter;
import com.sxf.crm.service.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    private final JwtRequestFilter jwtRequestFilter;

    public SecurityConfig(@Lazy JwtRequestFilter jwtRequestFilter) {
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                // 认证相关接口 - 公开访问
                .requestMatchers("/api/auth/**").permitAll()
                
                // 用户管理模块
                .requestMatchers("/api/users/**").hasAnyAuthority(
                    "user:view", "user:add", "user:edit", "user:delete"
                )
                
                // 角色管理模块
                .requestMatchers("/api/roles/**").hasAnyAuthority(
                    "role:view", "role:add", "role:edit", "role:delete"
                )
                
                // 权限管理模块
                .requestMatchers("/api/permissions/**").hasAnyAuthority(
                    "permission:view", "permission:create"
                )
                
                // 线索管理模块
                .requestMatchers("/api/clues/**").hasAnyAuthority(
                    "clue:list", "clue:create", "clue:edit", "clue:delete", 
                    "clue:view", "clue:assign", "clue:claim", "clue:accept", 
                    "clue:recycle", "clue:convert", "clue:followup"
                )
                
                // 客户管理模块
                .requestMatchers("/api/customers/**").hasAnyAuthority(
                    "customer:list", "customer:view", "customer:create", 
                    "customer:update", "customer:delete", "customer:edit", 
                    "customer:audit"
                )
                
                // 联系人管理模块
                .requestMatchers("/api/contacts/**").hasAnyAuthority(
                    "contact:list", "contact:view", "contact:create", 
                    "contact:update", "contact:delete", "contact:edit"
                )
                
                // 商机管理模块
                .requestMatchers("/api/opportunities/**").hasAnyAuthority(
                    "opportunity:create", "opportunity:update", "opportunity:view", 
                    "opportunity:list", "opportunity:claim", "opportunity:assign", 
                    "opportunity:accept", "opportunity:reject", "opportunity:recycle", 
                    "opportunity:lost", "opportunity:won", "opportunity:negotiating", 
                    "opportunity:pending-decision", "opportunity:in-progress", 
                    "opportunity:followed-up", "opportunity:followup"
                )
                
                // 拜访管理模块
                .requestMatchers("/api/visits/**").hasAnyAuthority(
                    "visit:create", "visit:edit", "visit:delete", 
                    "visit:view", "visit:list"
                )
                
                // 行业管理模块
                .requestMatchers("/api/industries/**").hasAuthority("industry:list")
                
                // 部门管理模块（预留）
                .requestMatchers("/api/departments/**").hasAnyAuthority(
                    "department:view", "department:create", "department:edit", "department:delete"
                )
                
                // 用户日志模块
                .requestMatchers("/api/user-logs/**").hasAuthority("userlog:view")
                
                // 线索日志模块
                .requestMatchers("/api/clue-logs/**").hasAuthority("clue:view")
                
                // 商机日志模块  
                .requestMatchers("/api/opportunity-logs/**").hasAuthority("opportunity:view")
                
                // 联系人部门关联模块
                .requestMatchers("/api/contact-departments/**").hasAnyAuthority(
                    "contact:view", "contact:edit"
                )
                
                // 客户部门关联模块
                .requestMatchers("/api/customer-departments/**").hasAuthority("customer:view")
                
                // 测试接口（可选择性开放或限制）
                .requestMatchers("/api/test/**").permitAll()
                
                // 其他所有请求都需要认证
                .anyRequest().authenticated()
            )
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider(UserDetailsServiceImpl userDetailsService) {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }
} 